Imports OMANE.Common.UI


Public Class Indicateur
    Inherits UIObject


    Private _Value As Object
    Public Property Value As Object
        Get
            Return _Value
        End Get
        Set(ByVal value As Object)
            _Value = value
            OnPropertyChanged("Value")
        End Set
    End Property

    Private _Name As String = ""
    Public Property Name As String
        Get
            Return _Name
        End Get
        Set(ByVal value As String)
            _Name = value
            OnPropertyChanged("Name")
        End Set
    End Property

    Private _DataSource As DataSource
    Public Property DataSource As DataSource
        Get
            Return _DataSource
        End Get
        Set(ByVal value As DataSource)
            _DataSource = value
            OnPropertyChanged("DataSource")
        End Set
    End Property

    Private _DataMember As DataSourceColumn
    Public Property DataMember As DataSourceColumn
        Get
            Return _DataMember
        End Get
        Set(ByVal value As DataSourceColumn)
            _DataMember = value
            OnPropertyChanged("DataMember")
        End Set
    End Property

    Private _Aggregate As String
    Public Property Aggregate As String
        Get
            Return _Aggregate
        End Get
        Set(ByVal value As String)
            _Aggregate = value
            OnPropertyChanged("Aggregate")
        End Set
    End Property

    Private _Type As String = "DataComputed"
    Public Property Type As String
        Get
            Return _Type
        End Get
        Set(ByVal value As String)
            _Type = value
            OnPropertyChanged("Type")
        End Set
    End Property

    Public Sub Compute()
        If Aggregate = "(Aucun)" Then
            Value = New DataView(DataSource.Data)
        End If
        If Aggregate = "Somme" Then
            Value = DataSource.Data.Compute("SUM(" & DataMember.Name & ")", "")
        End If
        If Aggregate = "Moyenne" Then
            Value = DataSource.Data.Compute("AVG(" & DataMember.Name & ")", "")
        End If
        If Aggregate = "Minimum" Then
            Value = DataSource.Data.Compute("MIN(" & DataMember.Name & ")", "")
        End If
        If Aggregate = "Maximum" Then
            Value = DataSource.Data.Compute("MAX(" & DataMember.Name & ")", "")
        End If
        If Aggregate = "Variance" Then
            Value = DataSource.Data.Compute("VAR(" & DataMember.Name & ")", "")
        End If
        If Aggregate = "Ecart-Type" Then
            Value = DataSource.Data.Compute("STDEV(" & DataMember.Name & ")", "")
        End If
        If Aggregate = "Nombre" Then
            Value = DataSource.Data.Compute("COUNT(" & DataMember.Name & ")", "")
        End If
        If Aggregate = "Nombre Distinct" Then

        End If
        If Aggregate = "Distinct" Then
            If DataSource.Data.DataSet Is Nothing Then
                Return
                Dim dset = New DataSet()
                dset.Tables.Add(DataSource.Data)
            End If
            If Not DataSource.Data.Columns.Contains("_Filter_") Then
                DataSource.Data.Columns.Add("_Filter_", GetType(Double), "1")
            End If
            If Not DataSource.Data.DataSet.Tables.Contains("table_" & DataMember.Name) Then
                Dim tbl = DataSource.Data.DefaultView.ToTable(True, DataMember.Name)
                tbl.Columns(0).ColumnName = "Member"
                tbl.TableName = "table_" & DataMember.Name
                'Dim col = tbl.Columns.Add("IsSelected", GetType(Double))
                'col.DefaultValue = 0.0
                'tbl.DefaultView.Sort = DataMember.Name & " ASC"

                DataSource.Data.DataSet.Tables.Add(tbl)
                Dim str = ""
                For Each r As DataRow In tbl.Rows
                    str = str & r(0).ToString() & vbCrLf
                Next
                'Windows.Clipboard.SetText(str)
                '  MsgBox(str)
                Dim rel = DataSource.Data.DataSet.Relations.Add("relation_" & DataMember.Name, tbl.Columns(0), DataSource.Data.Columns(DataMember.Name))

                tbl.Columns.Add("Count", GetType(Double), "Sum(Child(relation_" & DataMember.Name & ")._Filter_)")

                'ModuleDashboarding._activeproject.AddFilterTable(rel)
            End If
            DataSource.Data.DataSet.Tables("table_" & DataMember.Name).DefaultView.Sort = "Member Asc, Count Desc"
            Value = DataSource.Data.DataSet.Tables("table_" & DataMember.Name).DefaultView
        End If
    End Sub

    Private _DimensionSorting As String
    Public Property DimensionSorting As String
        Get
            Return _DimensionSorting
        End Get
        Set(ByVal value As String)
            _DimensionSorting = value
            OnPropertyChanged("DimensionSorting")
        End Set
    End Property

    Private _DimensionDataMember As DataSourceColumn
    Public Property DimensionDataMember As DataSourceColumn
        Get
            Return _DimensionDataMember
        End Get
        Set(ByVal value As DataSourceColumn)
            _DimensionDataMember = value
            OnPropertyChanged("DimensionDataMember")
        End Set
    End Property

    Public Sub ComputeWithDimension()
        If String.IsNullOrEmpty(Aggregate) Then
            Return
        End If
        If Aggregate = "(Aucun)" Then
            Return
        End If
        If Aggregate = "Nombre Distinct" Then
            Return
        End If
        If Aggregate = "Distinct" Then
            Return
        End If
        If Not DataSource.Data.Columns.Contains("_Filter_") Then
            DataSource.Data.Columns.Add("_Filter_", GetType(Double), "1")
        End If
        Dim indic = TryCast(DataSource, IndicateurDataSource)
        If DataSource.Data.DataSet Is Nothing Then
            Dim dset = New DataSet()
            dset.Tables.Add(DataSource.Data)
        End If

        If indic IsNot Nothing Then
            ComputeIndicateurWithDimension(indic)
            Return
        End If

        If Not DataSource.Data.Columns.Contains("_Filter_" & DataMember.Name) Then
            If DataSource.Data.Columns(DataMember.Name).DataType Is GetType(String) Then
                DataSource.Data.Columns.Add("_Filter_" & DataMember.Name, GetType(Double), "_Filter_")
            Else
                DataSource.Data.Columns.Add("_Filter_" & DataMember.Name, GetType(Double), "_Filter_*" & DataMember.Name)
            End If
        End If
        If WeightDataMember IsNot Nothing Then
            If WeightSorting <> "(Aucun)" Then
                If Not DataSource.Data.Columns.Contains("_Filter_" & WeightDataMember.Name) Then
                    If DataSource.Data.Columns(WeightDataMember.Name).DataType Is GetType(String) Then
                        DataSource.Data.Columns.Add("_Filter_" & WeightDataMember.Name, GetType(Double), "_Filter_")
                    Else
                        DataSource.Data.Columns.Add("_Filter_" & WeightDataMember.Name, GetType(Double), "_Filter_*" & WeightDataMember.Name)
                    End If
                End If
                If Not DataSource.Data.Columns.Contains("_Filter_" & DataMember.Name & "_Weight_" & WeightDataMember.Name) Then
                    If DataSource.Data.Columns(WeightDataMember.Name).DataType Is GetType(String) Then
                        DataSource.Data.Columns.Add("_Filter_" & DataMember.Name & "_Weight_" & WeightDataMember.Name, GetType(Double), "_Filter_")
                    Else
                        DataSource.Data.Columns.Add("_Filter_" & DataMember.Name & "_Weight_" & WeightDataMember.Name, GetType(Double), "_Filter_*" & DataMember.Name & "*" & WeightDataMember.Name)
                    End If
                End If
            End If
        End If
        
        If Not DataSource.Data.DataSet.Tables.Contains("table_" & DimensionDataMember.Name) Then
            Dim tbl = DataSource.Data.DefaultView.ToTable(True, DimensionDataMember.Name)
            tbl.Columns(0).ColumnName = "Member"
            tbl.TableName = "table_" & DimensionDataMember.Name
            DataSource.Data.DataSet.Tables.Add(tbl)
            DataSource.Data.DataSet.Relations.Add("relation_" & DimensionDataMember.Name, tbl.Columns(0), DataSource.Data.Columns(DimensionDataMember.Name))

            tbl.Columns.Add("Count", GetType(Double), "Sum(Child(relation_" & DimensionDataMember.Name & ")._Filter_)")
        End If

        'If WeightDataMember IsNot Nothing Then
        '    If WeightSorting <> "(Aucun)" Then

        '    End If
        'End If

        If Not DataSource.Data.DataSet.Tables("table_" & DimensionDataMember.Name).Columns.Contains("_" & Aggregate & "_" & DataMember.Name) Then
            Dim expr = "1"
            If Aggregate = "Somme" Then
                expr = "Sum(Child(relation_" & DimensionDataMember.Name & ")._Filter_" & DataMember.Name & ")"
            End If
            If Aggregate = "Moyenne" Then
                expr = "Avg(Child(relation_" & DimensionDataMember.Name & ")._Filter_" & DataMember.Name & ")"

                If WeightDataMember IsNot Nothing Then
                    If WeightSorting <> "(Aucun)" Then
                        expr = "Sum(Child(relation_" & DimensionDataMember.Name & ")._Filter_" & DataMember.Name & "_Weight_" & WeightDataMember.Name & ")/" & _
                              "Sum(Child(relation_" & DimensionDataMember.Name & ")._Filter_" & WeightDataMember.Name & ")"
                        'MsgBox(expr)
                    End If
                End If
            End If
            If Aggregate = "Minimum" Then
                expr = "Min(Child(relation_" & DimensionDataMember.Name & ")._Filter_" & DataMember.Name & ")"
            End If
            If Aggregate = "Maximum" Then
                expr = "Max(Child(relation_" & DimensionDataMember.Name & ")._Filter_" & DataMember.Name & ")"
            End If
            If Aggregate = "Variance" Then
                expr = "Var(Child(relation_" & DimensionDataMember.Name & ")._Filter_" & DataMember.Name & ")"
            End If
            If Aggregate = "Ecart-Type" Then
                expr = "StDev(Child(relation_" & DimensionDataMember.Name & ")._Filter_" & DataMember.Name & ")"
            End If
            If Aggregate = "Nombre" Then
                expr = "Sum(Child(relation_" & DimensionDataMember.Name & ")._Filter_" & DataMember.Name & ")"
            End If

            DataSource.Data.DataSet.Tables("table_" & DimensionDataMember.Name).Columns.Add("_" & Aggregate & "_" & DataMember.Name, GetType(Double), expr)
        End If

        Dim sortexpr = ""
        If DimensionSorting = "(Aucun)" Then
            'sortexpr = "Member ASC"
        End If
        If DimensionSorting = "Valeurs Croissantes" Then
            sortexpr = "_" & Aggregate & "_" & DataMember.Name & " ASC"
        End If
        If DimensionSorting = "Valeurs Decroissantes" Then
            sortexpr = "_" & Aggregate & "_" & DataMember.Name & " DESC"
        End If
        If DimensionSorting = "Libelles Croissants" Then
            sortexpr = "Member ASC, " & "_" & Aggregate & "_" & DataMember.Name & " DESC"
        End If
        If DimensionSorting = "Libelles Deroissants" Then
            sortexpr = "Member DESC, " & "_" & Aggregate & "_" & DataMember.Name & " DESC"
        End If
        If Not String.IsNullOrEmpty(sortexpr) Then
            DataSource.Data.DataSet.Tables("table_" & DimensionDataMember.Name).DefaultView.Sort = sortexpr
        End If
        'DataSource.Data.DataSet.Tables("table_" & DimensionDataMember.Name).DefaultView.Sort = "Count Desc"
        DataSource.Data.DataSet.Tables("table_" & DimensionDataMember.Name).DefaultView.RowFilter = "Count>0"
        Value = DataSource.Data.DataSet.Tables("table_" & DimensionDataMember.Name).DefaultView


        DataSource.Data.DataSet.Tables("table_" & DimensionDataMember.Name).WriteXml("dataset.xml", XmlWriteMode.WriteSchema)
    End Sub

    Private _WeightSorting As String
    Public Property WeightSorting As String
        Get
            Return _WeightSorting
        End Get
        Set(ByVal value As String)
            _WeightSorting = value
            OnPropertyChanged("WeightSorting")
        End Set
    End Property

    Private _WeightDataMember As DataSourceColumn
    Public Property WeightDataMember As DataSourceColumn
        Get
            Return _WeightDataMember
        End Get
        Set(ByVal value As DataSourceColumn)
            _WeightDataMember = value
            OnPropertyChanged("WeightDataMember")
        End Set
    End Property

    Private _Formula As String
    Public Property Formula As String
        Get
            Return _Formula
        End Get
        Set(ByVal value As String)
            _Formula = value
            OnPropertyChanged("Formula")
        End Set
    End Property

    Public Property XFormula As XElement

    Private Sub ComputeIndicateurWithDimension(ByVal indic As IndicateurDataSource)

        If Not ModuleDashboarding._activeproject.DataSet.Tables.Contains("table_" & DimensionDataMember.Name) Then
            Dim tbl = DataSource.Data.DefaultView.ToTable(True, DimensionDataMember.Name)
            tbl.Columns(0).ColumnName = "Member"
            tbl.TableName = "table_" & DimensionDataMember.Name
            DataSource.Data.DataSet.Tables.Add(tbl)
            DataSource.Data.DataSet.Relations.Add("relation_" & DimensionDataMember.Name, tbl.Columns(0), DataSource.Data.Columns(DimensionDataMember.Name))

            tbl.Columns.Add("Count", GetType(Double), "Sum(Child(relation_" & DimensionDataMember.Name & ")._Filter_)")
        End If

        Dim coltofilter As New List(Of DataColumn)
        Dim colexpr = FormulaExpression.GetTableString( _
                      FormulaExpression.Load(XFormula), _
                      DataSource.Data.DataSet.Tables("table_" & DimensionDataMember.Name), _
                      coltofilter)

        For Each c In coltofilter
            If Not DataSource.Data.Columns.Contains("_Filter_" & c.ColumnName) Then
                If c.DataType Is GetType(String) Then
                    c.Table.Columns.Add("_Filter_" & c.ColumnName, GetType(Double), "_Filter_")
                Else
                    c.Table.Columns.Add("_Filter_" & c.ColumnName, GetType(Double), "_Filter_*" & c.ColumnName)
                End If
            End If
        Next

        '.Columns.Add("tempcol", GetType(Double), GetTableString(expr, table, coltofilter))
    End Sub

End Class
